package org.oep.jmingle;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

class RecordStoreTools {

	private RecordStoreTools() {}
	
	public static void export(Hashtable table, String recordName) throws RecordStoreException {
		// Our data in memory should be up-to-date, so delete the record
		try {
			RecordStore.deleteRecordStore(recordName);
		}
		catch (RecordStoreException e) {
			
		}
		
		// Add the new one
		RecordStore rs = RecordStore.openRecordStore(recordName,true);
		
		Enumeration nodes = table.elements();
		
		for(int i = 0; i < table.size(); i++) {
			MingleNode node = (MingleNode) nodes.nextElement();
			byte [] record = SimpleRecord.createRecord(node.getAddress(), node.getName(), System.currentTimeMillis());
			
			rs.addRecord(record, 0, record.length);
		}
		rs.closeRecordStore();
	}
	
	public static void delete(String recordName) throws RecordStoreException {
		RecordStore.deleteRecordStore(recordName);
		RecordStore rs = RecordStore.openRecordStore(recordName, true);
		rs.closeRecordStore();	
	}
	
	public static int countRecords(String recordName) throws RecordStoreException {
		RecordStore rs = RecordStore.openRecordStore(recordName,true);
		int num = rs.getNumRecords();
		rs.closeRecordStore();
		return num;
	}
	
	public static boolean load(String recordName, Hashtable table) throws RecordStoreException {
		RecordStore rs = RecordStore.openRecordStore(recordName,true);
		RecordEnumeration enumerator = null;
		if(rs.getNumRecords() > 0) {
			try {
				enumerator = rs.enumerateRecords(null, null, false);
			}
			catch(Exception e) {
				if(rs != null)
					rs.closeRecordStore();
				System.out.println(e);
				return false;
			}
		}
		else {
			rs.closeRecordStore();
			return true;
		}
		while(enumerator.hasNextElement()) {
			byte [] record = enumerator.nextRecord();
			
			String name = SimpleRecord.getName(record);
			String address = SimpleRecord.getAddress(record);
			long time = SimpleRecord.getTime(record);
			
			MingleNode n = new MingleNode(name, address);
			n.setLastSeen(time);
			table.put(address, n);
			
			
			
			try {
				int pct = ((int) Runtime.getRuntime().freeMemory() * 100)  / (int)Runtime.getRuntime().totalMemory();
				if(pct <= 50) {
					System.gc();
				}
				Thread.sleep(5);
			} catch (Exception e) {
				
			}
		}
		rs.closeRecordStore();
		return true;
	}
	
	// this function always returns true! how positive of it! :D
	// seriously... i need to fix it but I won't.
	public static boolean update(MingleNode node, String recordName) throws RecordStoreException {
		RecordStore rs = RecordStore.openRecordStore(recordName,true);
		
		if(rs.getNumRecords() <= 0) {
			rs.closeRecordStore();
			RecordStoreTools.add(node, recordName);
			return true;
		}

			
		byte [] newRecord = SimpleRecord.createRecord(node.getAddress(), node.getName(), node.getLastSeen());
		for(int recID = 1; recID <= rs.getNumRecords(); recID++) {
			byte [] record = rs.getRecord(recID);
			String addy = SimpleRecord.getAddress(record);
			if(node.getAddress().compareTo(addy) == 0){
				System.out.println("RecordStoreTools: Updated existing record " + node.getAddress());
				rs.setRecord(recID, newRecord, 0, newRecord.length);
				rs.closeRecordStore();
				return true;
			}
		}
		rs.closeRecordStore();
		RecordStoreTools.add(node, recordName);
		return true;
	}
	
	public static void add(MingleNode node, String recordName) throws RecordStoreException {
		RecordStore rs = RecordStore.openRecordStore(recordName,true);
		byte [] newRecord = SimpleRecord.createRecord(node.getAddress(), node.getName(), node.getLastSeen());
		rs.addRecord(newRecord, 0, newRecord.length);
		rs.closeRecordStore();
	}
	
	public static byte[] fetchRecord(String recordName, String address) throws RecordStoreException {
		RecordStore rs = RecordStore.openRecordStore(recordName,true);
		RecordEnumeration enumerator = null;
		if(rs.getNumRecords() > 0) {
			try {
				enumerator = rs.enumerateRecords(null, null, false);
			}
			catch(Exception e) {
				if(rs != null)
					rs.closeRecordStore();
				System.out.println(e);
				return null;
			}
		}
		else {
			rs.closeRecordStore();
			return null;
		}
		
		while(enumerator.hasNextElement()) {
			byte [] record = enumerator.nextRecord();
			String addy = SimpleRecord.getAddress(record);
			if(address.compareTo(addy) == 0){
				rs.closeRecordStore();
				return record;
			}
		}
		rs.closeRecordStore();
		return null;
	}
	
	public static long getTime(String recordName, String address) {
		try {
			byte b[] = fetchRecord(recordName, address);
			if(b != null)
				return SimpleRecord.getTime(b);
			else
				return -1;
		}
		catch(RecordStoreException e) {
			return -1;
		}
	}
	
	public static String getName(String recordName, String address) {
		try {
			byte b[] = fetchRecord(recordName, address);
			if(b != null)
				return SimpleRecord.getName(b);
			else
				return null;
		}
		catch(RecordStoreException e) {
			return null;
		}
	}
}



